package com.gxgeek.springfeaturesstudy;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.ApplicationStartingEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author gaoxing
 * @create 2017-11-07 上午9:44
 */
@Component
@Slf4j
public class InitBean implements CommandLineRunner ,InitializingBean , ApplicationListener<ContextRefreshedEvent>
                        ,BeanFactoryPostProcessor,BeanPostProcessor,ApplicationContextAware,BeanNameAware,BeanFactoryAware {

    public InitBean() {
        log.info("bean 本身构造器启动 ");
    }

    @Override
    public void setBeanName(String s) {
        log.info("BeanNameAware 接口的: setBeanName : {}",s);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

        log.info("BeanFactoryAware 接口的: setBeanFactory{}-->{}",beanFactory);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

        log.info("执行ApplicationContextAware 的: setApplicationContext");

    }

    @PostConstruct
    public void postConstruct(){
        log.info("@PostConstruct 注解 的 postConstruct 方法启动");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("InitializingBean 接口的 afterPropertiesSet 方法启动");
    }


    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {

        log.info(getClass()+"ApplicationListener 接口 的 onApplicationEvent 方法启动:{}");
    }
    @EventListener({ApplicationReadyEvent.class})
    public void handleApplicationReadyEvent(ApplicationReadyEvent event) {
        event.getApplicationContext();

        log.info(getClass()+"ApplicationReadyEvent 事件");
    }
    @EventListener({ContextStartedEvent.class})
    public void handleContextStartedEvent(ContextStartedEvent event) {
        event.getApplicationContext();

        log.info(getClass()+"ContextStartedEvent 事件");
    }


    @Override
    public void run(String... strings) throws Exception {
        log.info("CommandLineRunner 接口的的 run 方法启动{}",strings);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        log.info("执行BeanFactoryPostProcessor 的: postProcessBeanFactory");

    }


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("BeanPostProcessor 接口的: postProcessBeforeInitialization {}-->{}",bean,beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("BeanPostProcessor 接口的: postProcessAfterInitialization{}-->{}",bean,beanName);
        return bean;
    }

}
